export default `
<template>
  <div id="map" class="map"></div>
</template>
<script>
import "ol/ol.css";
import Map from "ol/Map";
import View from "ol/View";
import layerTile from "ol/layer/Tile";
import OSM from "ol/source/OSM";
import LineString from "ol/geom/LineString";
import VectorSource from "ol/source/Vector";
import Vector from "ol/layer/Vector";
import Feature from "ol/Feature";
import { boundingExtent } from "ol/extent";
import Point from "ol/geom/Point";
import { Icon, Style, Stroke, Fill, Text } from "ol/style";
import white_point_icon from "./images/white_point_icon.png";
import text_blue from "./images/text_blue.png";
import { lineListData } from "./lineData.js";

export default {
  name: "drawArrowRoute",
  data() {
    return {
      map: null,
      roadLineLayer: null,  // 轨迹图层
    };
  },
  mounted() {
    this.$nextTick(() => {
      this.initMap();
    });
  },
  methods: {
    // 初始化
    initMap() {
      this.map = new Map({
        target: "map",
        layers: [
          new layerTile({
            source: new OSM(),
          }),
        ],
        view: new View({
          projection: "EPSG:4326",
          center: [Number(116.3672), Number(23.5772)],
          zoom: 15,
        }),
      });
      // 绘制路径
      this.drawLine(lineListData);
    },
    // 绘制路径
    drawLine(lineData) {
      const pointsList = [];
      lineData.forEach((value) => {
          pointsList.push([value.longitude, value.latitude]);
      });
    
      // 绘制带有箭头效果的轨迹
      this.roadLineLayer = new Vector({
        source: new VectorSource(),
        style: this.styleArrowFunction,
      });
      this.map.addLayer(this.roadLineLayer);
      for (let i = 0; i < lineData.length - 1; i++) {
        const initPos = pointsList[i];
        const targetPos = pointsList[i + 1];
        const coordinates = [initPos, targetPos];
        const lineFeature = new Feature({
          geometry: new LineString(coordinates),
        });
        this.roadLineLayer.getSource().addFeature(lineFeature);
      }

      this.drawLoc();
    },
    // 绘制位置标示
    drawLoc(opt = {}) {
      if (lineListData.length == 0) {
        return false;
      }
      let pointsList = [];
      let onlyPointList = []
      lineListData.forEach((value) => {
        onlyPointList.push([value.longitude, value.latitude])
        pointsList.push({
            data: value,
            pointLoc: [value.longitude, value.latitude],
        });
      });
      const vectorSource = new VectorSource({ features: [new Feature([])] }); // 矢量标注的数据源
      var features = new Array(pointsList.length);
      for (let idx = 0; idx < pointsList.length; idx++) {
        features[idx] = new Feature({
          // 新建一个要素 ol.Feature
          geometry: new Point(pointsList[idx]["pointLoc"] || []),
          data: pointsList[idx],
        });
        // 添加文字 设置要素的样式
        let obj = {
          imageSrc: opt.imageSrc || white_point_icon,
          text: pointsList[idx]["data"]["indexTxt"],
          opacity: 0.9,
          zIndex: 20,
          fill: "#111",
        };
        features[idx].setStyle(this.createStyleFun(obj));
      }
      vectorSource.addFeatures(features); // 将新要素添加到数据源中
      this.vectorLayer = new Vector({ source: vectorSource }); // 矢量标注图层
      this.map.addLayer(this.vectorLayer);
      this.viewExtent(onlyPointList);   // 视野自适应
    },
    // 视野自适应
    viewExtent(coordinates) {
      this.extent = new boundingExtent(coordinates);
      if (this.map) {
        this.map.getView().fit(this.extent, this.map.getSize());
        this.map.getView().setZoom(this.map.getView().getZoom() - 0.1);
      }
    },
    // 路径轨迹样式
    styleArrowFunction(feature) {
      let zoom = Math.round(this.map.getView().getZoom());
      if (zoom < 8) zoom = 8;
      let styles = [];
      styles.push(
        new Style({
          zIndex: 30,
          stroke: new Stroke({
            color: "#10a2ff",
            width: 8,
          }),
        })
      );
      const _coords = feature.get("geometry").getCoordinates();
      const initPos = _coords[0];
      const targetPos = _coords[1];
      const minZoomLevel = 8; // 最小等级，8
      const minZLMaxPer = 200;

      const per = minZLMaxPer / Math.pow(2, zoom - minZoomLevel); // 1000单位经纬距离箭头数量；箭头间隔随地图层级变化
      let count = Math.round((this.getDistance(initPos, targetPos) / per) * 1000); // 箭头数量 count
      let points = [];
      let angleArr = [];
      let lastPoint = initPos;
      for (let i = 1; i < count; i++) {
        const x = this.effect(initPos[0], targetPos[0], i, count);
        const y = this.effect(initPos[1], targetPos[1], i, count);
        const angle = Math.atan2(x - lastPoint[0], y - lastPoint[1]);
        points.push([x, y]);
        angleArr.push(angle);
        lastPoint = [x, y];
      }
      for (let i = 0; i < points.length; i++) {
        const point = new Point(points[i]);
        styles.push(
          new Style({
            geometry: point,
            zIndex: 100,
            image: new Icon({
              src: require("./images/up.png"),
              anchor: [0.5, 0.5],
              rotateWithView: true,
              rotation: angleArr[i],
            }),
          })
        );
      }
      return styles;
    },
    // 获取2点之间的距离
    getDistance(pxA, pxB) {
      return Math.sqrt(Math.pow(pxA[0] - pxB[0], 2) + Math.pow(pxA[1] - pxB[1], 2));
    },
    // ?不知道是不是用来拆分线段
    effect(initPos, targetPos, currentCount, count) {
      let b = initPos;
      let c = targetPos - initPos;
      let t = currentCount;
      let d = count;
      return (c * t) / d + b;
    },
    // 样式
    createStyleFun(opt = {}) {
      let styleObj = new Style({
        image: new Icon({
          opacity: opt.opacity || 0.75,
          anchor: [0.5, 0.9],
          src: opt.imageSrc || white_point_icon, // text_blue、white_point_icon
        }),
        text: new Text({
          textAlign: "center", // 位置
          font: "14px Microsoft YaHei UI",
          offsetX: 1,
          offsetY: -16,
          text: '"'+opt.text+'"', // 文本内容
          fill: new Fill({ color: opt.fill || "#111" }), // 文本填充样式（即文字颜色）
          stroke: opt.stroke == undefined ? "" : new Stroke({ color: opt.stroke || "#111", width: 14 }),
        }),
        zIndex: opt.zIndex || 10,
      });
      return styleObj;
    },
  },
};
</script>

<style lang="less" scoped>
.map {
  height: 100%;
}
</style>
`